package com.mark.web.sys.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.mark.common.Constant;
import com.mark.common.ServerResponse;
import com.mark.common.utils.MD5Util;
import com.mark.web.sys.common.enmus.UserStateEnum;
import com.mark.web.sys.entity.po.Department;
import com.mark.web.sys.entity.po.Role;
import com.mark.web.sys.mapper.DepartmentMapper;
import com.mark.web.sys.mapper.RoleMapper;
import com.mark.web.sys.mapper.UserMapper;
import com.mark.web.sys.entity.po.User;
import com.mark.web.sys.entity.vo.UserVo;
import com.mark.web.sys.service.IUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @Description: 系统用户的业务实现类
 * @Author: Kingsley
 * @CreateDate: 2019/1/1 15:30
 * @Version: 2.0
 * @Copyright : 豆浆油条个人非正式工作室
 */
@Service(value = "sysUserService")
public class UserServiceImpl implements IUserService {

    private final UserMapper userMapper;
    private final StringRedisTemplate redisTemplate;
    private final RoleMapper roleMapper;
    private final DepartmentMapper departmentMapper;

    @Autowired
    public UserServiceImpl(UserMapper userMapper, StringRedisTemplate redisTemplate, RoleMapper roleMapper, DepartmentMapper departmentMapper) {
        this.userMapper = userMapper;
        this.redisTemplate = redisTemplate;
        this.roleMapper = roleMapper;
        this.departmentMapper = departmentMapper;
    }

    @Override
    public ServerResponse<Map<String, Object>>  registerSimple(User user) {
        return this.register(user,true);
    }

    @Override
    public ServerResponse<String> checkValid(String value, String type) {
        //校验用户名
        if (UserStateEnum.USERNAME.getType().equals(type)) {
            if (userMapper.checkUserName(value) > 0) {
                return ServerResponse.createByErrorMessage("抱歉该用户名已经被注册！");
            }
        }
        //校验邮箱
        if (UserStateEnum.EMAIL.getType().equals(type)) {
            if (userMapper.checkEmail(value) > 0) {
                return ServerResponse.createByErrorMessage("抱歉该邮箱已经被注册！");
            }
        }
        //校验手机号码
        if(UserStateEnum.PHONE.getType().equals(type)){
            if (userMapper.checkPhone(value) > 0) {
                return ServerResponse.createByErrorMessage("抱歉该手机号已经被注册！");
            }
        }
        return ServerResponse.createBySuccessMessage("校验成功");
    }

    @Override
    public ServerResponse<User> login(String type, String typeValue, String password) {
        ServerResponse<String> response = this.checkValid(typeValue, type);
        if (response.isSuccess()) {
            return ServerResponse.createByErrorMessage("登录账号不存在！");
        } else {
            String username = null;
            String email = null;
            String phone = null;
            if(UserStateEnum.USERNAME.getType().equals(type)){
                username = typeValue;
            }else if (UserStateEnum.EMAIL.getType().equals(type)){
                email = typeValue;
            }else if(UserStateEnum.PHONE.getType().equals(type)){
                phone = typeValue;
            }
            User user = userMapper.selectLogin(username,email,phone,typeValue, password);
            if (user == null) {
                return ServerResponse.createByErrorMessage("密码错误！请重新登录");
            }
            //系统存在该用户，但是用户的状态是否可用，在ShiroRealm中验证
            return ServerResponse.createBySuccess("用户验证成功", user);
        }
    }

    @Override
    public ServerResponse<Map<String, Object>>  register(User user) {
        return this.register(user, false);
    }

    @Override
    public ServerResponse<UserVo> getCurrentUser(int currentUserId) {
        User user = userMapper.selectByPrimaryKey(currentUserId);
        if(user == null){
            ServerResponse.createByError();
        }
        UserVo userVo = new UserVo();
        userVo = userVo.assembleUserVo(user);
        return ServerResponse.createBySuccess(userVo);
    }


    @Override
    public ServerResponse<String> selectQuestion(String username) {
        //先验证用户信息,如果用户名存在则返回true
        ServerResponse validResponse = checkValid(username, UserStateEnum.USERNAME.getType());
        if (validResponse.isSuccess()) {
            return ServerResponse.createByErrorMessage("用户名不存在！");
        }else{
            String question = userMapper.selectQuestionByUserName(username);
            if (StringUtils.isNotBlank(question)) {
                return ServerResponse.createBySuccessMessage(question);
            }
            return ServerResponse.createByErrorMessage("抱歉！找不到你的问题！");
        }
    }

    @Override
    public ServerResponse<String> checkAnswer(String username, String question, String answer) {
        int resultCount = userMapper.checkAnswer(username, question, answer);
        //如果回答正确,生产一个随机数作为token，并将token保存到redis中
        if (resultCount > 0) {
            String forgetToken = UUID.randomUUID().toString();
            //
            redisTemplate.opsForValue().set(Constant.RedisCache.TOKEN_PREFIX+username,
                    forgetToken,Constant.RedisCache.USER_FORGET_TOKEN_EXPIRE,
                    TimeUnit.SECONDS);
            return ServerResponse.createBySuccess(forgetToken);
        }
        return ServerResponse.createByErrorMessage("回答错误!");
    }

    @Override
    public ServerResponse<String> forgetResetPassword(String username, String passwordNew, String forgetToken) {
        //校验当前用户,如果用户名存在返回false
        ServerResponse validResponse = checkValid(username, Constant.USERNAME);
        if (validResponse.isSuccess()) {
            return ServerResponse.createByErrorMessage("用户不存在");
        }
        String token = redisTemplate.opsForValue().get(Constant.RedisCache.TOKEN_PREFIX + username);
        if (StringUtils.isBlank(token)) {
            return ServerResponse.createByErrorMessage("token无效或已经过期");
        }
        if (StringUtils.equals(forgetToken, token)) {
            passwordNew = MD5Util.md5EncodeUtf8(passwordNew);
            int rowCount = userMapper.updatePasswordByUsername(username, passwordNew);
            if (rowCount == Constant.SUCCESS) {
                return ServerResponse.createBySuccessMessage("修改密码成功");
            }
        } else {
            return ServerResponse.createByErrorMessage("token过期,请重置上一步操作");
        }
        return ServerResponse.createByErrorMessage("修改密码失败");
    }

    /**
     * 9.更新密码
     *
     * @param passwordOld   ： 旧密码
     * @param passwordNew   ：新密码
     * @param currentUserId ：
     * @return ：更新密码的结果
     */
    @Override
    public ServerResponse<String> resetPassword(String passwordOld, String passwordNew, int currentUserId) {
        //防止横向越权,要校验一下这个用户的旧密码,一定要指定是这个用户
        //密码加密
        passwordNew = MD5Util.md5EncodeUtf8(passwordNew);
        passwordOld = MD5Util.md5EncodeUtf8(passwordOld);
        //检查旧密码
        int resultCount = userMapper.checkPassword(passwordOld, currentUserId);
        if (resultCount == 0) {
            return ServerResponse.createByErrorMessage("输入的旧密码不正确");
        }
        User user = userMapper.selectByPrimaryKey(currentUserId);
        user.setPassword(passwordNew);
        int updateCount = userMapper.updateByPrimaryKeySelective(user);
        if (updateCount > 0) {
            return ServerResponse.createBySuccessMessage("更新密码成功！");
        }else{
            return ServerResponse.createByErrorMessage("更新密码失败！");
        }
    }

    /**
     * 10.更新用户信息
     *
     * @param user ：用户对象
     * @return ：更新成功返回更新后的用户信息
     */
    @Override
    public ServerResponse<UserVo> updateInformation(User user) {
        //email也要进行一个校验,校验新的email是不是已经存在,并且存在的email如果相同的话,不能是我们当前的这个用户的.
        int resultCount = userMapper.checkEmailByUserId(user.getEmail(), user.getId());
        if (resultCount > 0) {
            return ServerResponse.createByErrorMessage("该邮箱已经被注册！请重新输入新的邮箱");
        }
        //同理：校验用户名
        resultCount = userMapper.checkUsernameByUserId(user.getUsername(), user.getId());
        if (resultCount > 0) {
            return ServerResponse.createByErrorMessage("该用户名已经被注册！请重新输入新的用户名");
        }
        //同理：校验手机号
        resultCount =  userMapper.checkPhoneByUserId(user.getPhone(), user.getId());
        if(resultCount > 0){
            return ServerResponse.createByErrorMessage("该手机号已经被注册！请重新输入新的手机号");
        }
        //角色的设置
        if(user.getFkRoleId() == null){
            user.setFkRoleId(2);
        }else{
            Role role = roleMapper.selectByPrimaryKey(user.getFkRoleId());
            if(role == null){
                return ServerResponse.createByIllegalArgument("该角色不存在！");
            }
        }
        //部门的设置
        if(user.getFkDeptId() == null){
            user.setFkDeptId(1);
        }else{
            Department department = departmentMapper.selectByPrimaryKey(user.getFkDeptId());
            if(department == null){
                return ServerResponse.createByIllegalArgument("该部门不存在！");
            }
        }
        //如果性别为空则默认设置为保密
        if(user.getGender() == null){
            user.setGender((short) UserStateEnum.SECURITY.getState());
        }

        int updateCount = userMapper.updateByPrimaryKeySelective(user);
        if (updateCount == Constant.SUCCESS) {
            UserVo userVo = new UserVo();
            user = userMapper.selectByPrimaryKey(user.getId());
            userVo = userVo.assembleUserVo(user);
            return ServerResponse.createBySuccess("更新个人信息成功",userVo);
        }
        return ServerResponse.createByErrorMessage("更新个人信息失败");
    }

    /**
     * 5.获取当前的用户信息
     *
     * @param currentUserId ：存储在redis当前的用户的id
     * @return ：根据id查询在数据库中的用户信息
     */
    @Override
    public ServerResponse<UserVo> getInfo(Integer currentUserId) {
        User user = userMapper.selectByPrimaryKey(currentUserId);
        if (user != null) {
            user.setPassword(StringUtils.EMPTY);
            UserVo userVo = new UserVo();
            userVo = userVo.assembleUserVo(user);
            return ServerResponse.createBySuccess(userVo);
        }
        return ServerResponse.createByErrorMessage("当前用户不存在！");
    }

    /**
     * 11.更新用户头像
     *
     * @param currentUserId ：当前的用户id
     * @param imageUrl      ：头像的地址
     * @return ： 更新的结果
     */
    @Override
    public ServerResponse updateImageUrl(int currentUserId, String imageUrl) {
        User user = userMapper.selectByPrimaryKey(currentUserId);
        if (user != null) {
            user.setUserImg(imageUrl);
            int effectNumber = userMapper.updateByPrimaryKeySelective(user);
            if (effectNumber > 0) {
                UserVo userVo = new UserVo();
                userVo = userVo.assembleUserVo(user);
                return ServerResponse.createBySuccess(userVo);
            }
        }
        return ServerResponse.createByErrorMessage("更新头像失败");
    }

    /*
     *--------------------------------------- 以下是后台调用的接口 ------------------------------------
     */
    @Override
    public PageInfo<UserVo> getUserList(int pageNum, int pageSize) {
        PageHelper.startPage(pageNum,pageSize);
        List<User> userList = userMapper.selectList();
        List<UserVo> userVoList = Lists.newArrayList();
        for(User user : userList){
            UserVo userVo = new UserVo();
            userVo = userVo.assembleUserVo(user);
            userVoList.add(userVo);
        }
        PageInfo<UserVo> result = new PageInfo<>(userVoList);
        result.setTotal(new PageInfo<>(userList).getTotal());
        return result;
    }

    @Override
    public ServerResponse setUserEnableStatus(Integer userId, Integer newStatus, String remark) {
        int resultCount = userMapper.updateStatusByPrimaryKey(userId, remark, newStatus);
        if (resultCount > 0) {
            return ServerResponse.createBySuccess("更新用户状态成功");
        }
        return ServerResponse.createByErrorMessage("更改用户状态失败");
    }

    @Override
    public ServerResponse searchUsers(int pageNum, int pageSize, String userName, Integer userId, Integer status) {
        PageHelper.startPage(pageNum,pageSize);
        if(StringUtils.isNotBlank(userName)){
            userName = new StringBuilder().append("%").append(userName).append("%").toString();
        }else{
            userName = null;
        }
        List<User> userList = userMapper.searchUsers(userName,userId,status);
        List<UserVo> userVoList = Lists.newArrayList();
        for(User user : userList){
            UserVo userVo = new UserVo();
            userVo = userVo.assembleUserVo(user);
            userVoList.add(userVo);
        }
        PageInfo pageResult = new PageInfo(userList);
        pageResult.setList(userVoList);
        return ServerResponse.createBySuccess(pageResult);
    }

    /*
     * -------------------------------------- private methods----------------------------------------------------------
     */
    /**
     * 用户注册【简单注册、普通注册】
     * @param user ：用户对象
     * @param isSimple：是否简单注册；简单注册为true，反之为false
     * @return ：注册成功返回用户名
     */
    @SuppressWarnings("unchecked")
    private ServerResponse<Map<String, Object>> register(User user, boolean isSimple) {

        //校验用户名是否已经存在
        ServerResponse validResponse = this.checkValid(user.getUsername(), UserStateEnum.USERNAME.getType());
        if (!validResponse.isSuccess()) {
            return validResponse;
        }
        if(!isSimple){
            //校验邮箱是否已经存在
            validResponse = this.checkValid(user.getEmail(), UserStateEnum.EMAIL.getType());
            if (!validResponse.isSuccess()) {
                return validResponse;
            }
            //手机号的验证
            validResponse = this.checkValid(user.getPhone(), UserStateEnum.PHONE.getType());
            if (!validResponse.isSuccess()) {
                return validResponse;
            }
        }
        //密码MD5加上盐值加密
        user.setPassword(MD5Util.md5EncodeUtf8(user.getPassword()));
        //角色的设置
        if(user.getFkRoleId() == null){
            user.setFkRoleId(2);
        }else{
            Role role = roleMapper.selectByPrimaryKey(user.getFkRoleId());
            if(role == null){
                return ServerResponse.createByIllegalArgument("该角色不存在！");
            }
        }
        //部门的设置
        if(user.getFkDeptId() == null){
            user.setFkDeptId(1);
        }else{
            Department department = departmentMapper.selectByPrimaryKey(user.getFkDeptId());
            if(department == null){
                return ServerResponse.createByIllegalArgument("该部门不存在！");
            }
        }

        //如果性别为空则默认设置为保密
        if(user.getGender() == null){
            user.setGender((short) UserStateEnum.SECURITY.getState());
        }

        //状态默认值为1[可用]
        user.setEnableStatus(UserStateEnum.SUCCESS.getState());
        int resultCount  = userMapper.insert(user);
        if (resultCount == 0) {
            return ServerResponse.createByErrorMessage("注册失败！");
        }
        Map<String, Object> resultMap = Maps.newHashMap();
        resultMap.put("username", user.getUsername());
        return ServerResponse.createBySuccess("注册成功", resultMap);
    }


}
